﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Zipun.VkOnlineMusic.Logic;
using Zipun.VkOnlineMusic.View.WinForms.Controls;
using Zipun.VkOnlineMusic.View.WinForms.Properties;

namespace Zipun.VkOnlineMusic.View.WinForms
{
    public partial class MainForm : Form
    {
        private readonly Player _player;

        private const int WmNclbuttondown = 0xA1;
        private const int HtCaption = 0x2;
        //
        // Window states
        // 
        private const int ShowWindowMinimized = 2;

        [DllImport("user32.dll")]
        private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
        [DllImportAttribute("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
        [DllImport("user32.dll")]
        public static extern bool ReleaseCapture();

        public MainForm()
        {
            InitializeComponent();
            _player = new Player();
            _player.PlayStateChanged += player_PlayStateChange;
            _player.NowPlayingChanged += player_NowPlayingChanged;
            playPictureBox.Text = Resources.MainForm_Play;
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            var loginForm = new LoginForm();
            var dr = loginForm.ShowDialog();
            if (dr != DialogResult.OK) Close();
            _player.Initialize(loginForm.VkToken);
            audioList.SetAudios(_player.Audios);
            audioList.AudioChangedByUser += audioList_AudioChangedByUser;
            _selectedMenuitem = myAudioLabel;
            initializePlayback(PlayerMode.MyAudio);
        }

        private void player_NowPlayingChanged(object sender, EventArgs e)
        {
            audioList.SetNowPlaying(_player.NowPlaying);
        }

        private void player_PlayStateChange(object sender, PlayStateChangedEventArgs e)
        {
            switch (e.NewState)
            {
                case PlayState.Playing:
                    playPictureBox.Text = Resources.MainForm_Pause;
                    playPictureBox.Image = Resources.Pause_32;
                    break;
                case PlayState.Paused:
                case PlayState.Stopped:
                    playPictureBox.Text = Resources.MainForm_Play;
                    playPictureBox.Image = Resources.Play_32;
                    break;
            }
        }

        private void playPausePlaybackButton_Click(object sender = null, EventArgs e = null)
        {
            //
            // Now playing
            //
            if (_player.PlayState == PlayState.Playing)
            {
                // Pause
                _player.Pause();
                return;
            }
            //
            // Now paused
            //
            if (_player.PlayState == PlayState.Paused)
            {
                _player.Play();
                return;
            }
            //
            // Now stopped
            //
            var audio = audioList.SelectedItem;
            if (audio == null)
                return;
            _player.Play(audio);
        }

        private void audioList_AudioChangedByUser(object sender, AudioChangedByUserEventArgs e)
        {
            if (e.SelectedAudio == null)
                return;
            _player.Play(e.SelectedAudio);
        }

        private void nextButton_Click(object sender, EventArgs e)
        {
            _player.GotoNext();
        }

        private void previousButton_Click(object sender, EventArgs e)
        {
            _player.GotoPrevious();
        }

        private void shuffleButton_Click(object sender, EventArgs e)
        {
            _player.Shuffle = !_player.Shuffle;
            shufflePictureBox.Image = _player.Shuffle ? Resources.Shuffle_32 : Resources.Shuffle_Unchecked_32;
        }

        private void titlebarPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(Handle, WmNclbuttondown, HtCaption, 0);
            }
        }

        private void controlBoxButtonMouseHover(object sender, EventArgs e)
        {
            var control = sender as Control;
            if (control == null)
                return;
            control.ForeColor = Color.White;
            control.BackColor = Color.Black;
        }

        private void controBoxButtonMouseLeave(object sender, EventArgs e)
        {
            var control = sender as Control;
            if (control == null)
                return;
            control.ForeColor = Color.LimeGreen;
            control.BackColor = Color.Transparent;
        }

        private void closeLabel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void minimizeLabel_Click(object sender, EventArgs e)
        {
            ShowWindowAsync(Handle, ShowWindowMinimized);
        }

        private void playback32Button_MouseHover(object sender, EventArgs e)
        {
            var p = sender as Control;
            if (p == null)
                return;
            p.BackgroundImage = Resources.Empty_Hover_32;
        }

        private void playback24Button_MouseHover(object sender, EventArgs e)
        {
            var p = sender as Control;
            if (p == null)
                return;
            p.BackgroundImage = Resources.Empty_Hover_24;
        }

        private void playbackButton_MouseLeave(object sender, EventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.BackgroundImage = null;
        }

        private void playPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = _player.PlayState == PlayState.Playing ? Resources.Pause_Active_32 : Resources.Play_Active_32;
        }

        private void playPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = _player.PlayState == PlayState.Playing ? Resources.Pause_32 : Resources.Play_32;
        }

        private void previousPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.PlayPrevious_Active_24;
        }

        private void previousPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.PlayPrevious_24;
        }

        private void nextPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.PlayNext_Active_24;
        }

        private void nextPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.PlayNext_24;
        }

        private void shufflePictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.Shuffle_Active_32;
        }

        private void shufflePictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = _player.Shuffle ? Resources.Shuffle_32 : Resources.Shuffle_Unchecked_32;
        }

        private Control _selectedMenuitem;
        private void menuItemClick(Control item)
        {
            if (item == null)
                return;
            if (item == _selectedMenuitem)
                return;
            if (_selectedMenuitem != null)
            {
                _selectedMenuitem.Font = new Font(_selectedMenuitem.Font.FontFamily, 12);
                _selectedMenuitem.ForeColor = Color.LimeGreen;
            }
            item.Font = new Font(item.Font.FontFamily, 13);
            item.ForeColor = Color.White;
            _selectedMenuitem = item;
        }

        private void myAudioLabel_Click(object sender, EventArgs e)
        {
            if (_selectedMenuitem != null && _selectedMenuitem.Equals(sender))
                return;
            menuItemClick(sender as Control);
            _player.Initialize(PlayerMode.MyAudio);
            initializePlayback(PlayerMode.MyAudio);
            audioList.SetAudios(_player.Audios);
        }

        private void suggestionsLabel_Click(object sender, EventArgs e)
        {
            menuItemClick(sender as Control);
            _player.Initialize(PlayerMode.Suggestions);
            initializePlayback(PlayerMode.Suggestions);
            audioList.SetAudios(_player.Audios);
        }

        private void initializePlayback(PlayerMode playerMode)
        {
            addPictureBox.Visible = true;
            deletePictureBox.Visible = true;
            switch (playerMode)
            {
                case PlayerMode.MyAudio:
                    addPictureBox.Visible = false;
                    break;
                case PlayerMode.Suggestions:
                    deletePictureBox.Visible = false;
                    break;
            }
        }

        private void addPictureBox_Click(object sender, EventArgs e)
        {
            if (audioList.SelectedItem == null)
                return;
            _player.AddAudio(audioList.SelectedItem);
        }

        private void addPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.Add_Active_32;
        }

        private void addPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.Add_32;
        }

        private void deletePictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.Delete_Active_32;
        }

        private void deletePictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            var p = sender as PictureBox;
            if (p == null)
                return;
            p.Image = Resources.Delete_32;
        }

        private void deletePictureBox_Click(object sender, EventArgs e)
        {
            if (_player.DeleteAudio(audioList.SelectedItem))
                audioList.Remove(audioList.SelectedItem);
        }
    }
}
